<?php

namespace common\logics\trade\broadcast;

use Yii;
use yii\db\Exception;
use common\helpers\MathHelper;
use common\helpers\ArrayHelper;
use common\models\trade\Trade;
use common\models\shop\ShopOrder;
use common\models\shop\ShopOrderRefund;
use common\models\shop\ShopOrderRefundGoods;
use common\models\shop\ShopOrderGoods;
use common\logics\trade\scope\CompatibleScopeShopRefundOrder;
use common\models\user\UserCoupon;
use common\models\shop\ShopOrderCoupon;
use common\models\shop\ShopOrderDiscount;

/**
 * 商城业务订单-退款回调通知处理
 *
 * @author emhome <emhome@163.com>
 * @since 2.0
 */
class ShopRefundBroadcast extends BusinessNotifyBaseModel {

    /**
     * @var string 业务退款通知订单模型类名
     */
    public $modelClass = CompatibleScopeShopRefundOrder::class;

    /**
     * 处理退款消息业务通知
     * @return bool
     */
    public function transactNotify() {
        /* @var $trade Trade */
        $trade = $this->trade;
        /* @var $orderRefund CompatibleScopeShopRefundOrder */
        $orderRefund = $this->getOrderModel();
        $orderRefund->refund_time = $trade->updated_at;
        $orderRefund->status = ShopOrderRefund::STATUS_SUCCESS;
        $orderRefund->mark = '退款已到账';
        if (!$orderRefund->save()) {
            Yii::error($orderRefund->getErrorMsg(), 'payment');
            $msg = '业务退款保存失败！';
            return false;
        }
        //继续退款流程下一步操作
        $orderRefund->nextWorkflow();
        /* @var $order ShopOrder */
        $order = $orderRefund->order;
        if (!$order) {
            $msg = '退款已成功。业务订单未找到！';
            return true;
        }
        //退款总金额
        $refundAmount = $orderRefund->sameRefundAmount;
        $same = MathHelper::bccomp($refundAmount, $order->pay);
        if ($same !== 0) {
            Yii::error([
                $refundAmount,
                $order->pay,
                $same,
            ], 'payment');
            $msg = '金额不一致！';
            return true;
        }
        //关闭订单
        $order->status = $order::STATUS_CLOSE;
        if (!$order->save()) {
            Yii::error($order->getErrorMsg(), 'payment');
            $msg = '订单关闭保存失败！';
            return false;
        }

        /* @var $orderRefundGoods ShopOrderRefundGoods[] */
        $orderRefundGoods = $orderRefund->refundGoods;
        if (!empty($orderRefundGoods)) {
            foreach ($orderRefundGoods as $goods) {
                //回收库存
                $sku = $goods->goods;
                $sku->stock += $goods->goods_number;
                if ($sku->total < $sku->stock) {
                    $sku->total = $sku->stock;
                    $sku->shelf = $sku->stock;
                }
                if (!$sku->save()) {
                    throw new Exception('库存回收失败，' . $sku->getErrorMsg());
                }
                //回收订单商品优惠
                $goodsRefundDiscounts = $goods->refundDiscounts;
                foreach ($goodsRefundDiscounts as $goodsRefundDiscount) {
                    $goodsRefundDiscount->status = ShopOrderDiscount::STATUS_REFUND;
                    if (!$goodsRefundDiscount->save()) {
                        throw new Exception('订单优惠券退回失败，' . $goodsRefundDiscount->getErrorMsg());
                    }
                }
            }
        } else {
            /* @var $orderGoods ShopOrderGoods[] */
            $orderGoods = $order->goods;
            foreach ($orderGoods as $goods) {
                //回收库存
                $sku = $goods->goods;
                $sku->stock += $goods->goods_number;
                if ($sku->total < $sku->stock) {
                    $sku->total = $sku->stock;
                    $sku->shelf = $sku->stock;
                }
                if (!$sku->save()) {
                    throw new Exception('库存回收失败，' . $sku->getErrorMsg());
                }
                $goods->status = ShopOrderGoods::STATUS_RETURN;
                if (!$goods->save()) {
                    throw new Exception('订单商品取消失败，' . $goods->getErrorMsg());
                }
                //回收订单商品优惠
                $goodsRefundDiscounts = $goods->refundDiscounts;
                foreach ($goodsRefundDiscounts as $goodsRefundDiscount) {
                    $goodsRefundDiscount->status = ShopOrderDiscount::STATUS_REFUND;
                    if (!$goodsRefundDiscount->save()) {
                        throw new Exception('订单优惠券退回失败，' . $goodsRefundDiscount->getErrorMsg());
                    }
                }
            }

            //回收订单优惠券
            $orderDiscountCoupons = ShopOrderCoupon::find()->andWhere([
                'and',
                ['unified_id' => $order->unified_id],
                ['activity_id' => 0],
                ['>', 'discount_expired_at', time()],
                ['>', 'user_coupon_id', 0],
                ['coupon_refund_at' => 0],
                ['!=', 'status', ShopOrderCoupon::STATUS_DEFAULT],
            ])->all();
            $refundOrderCoupons = [];
            $orderReturnCoupons = [];
            foreach ($orderDiscountCoupons as $orderDiscountCoupon) {
                $userCouponId = $orderDiscountCoupon->user_coupon_id;
                $refundOrderCoupons[$userCouponId][] = $orderDiscountCoupon;
                if (!isset($orderReturnCoupons[$userCouponId])) {
                    $orderReturnCoupons[$userCouponId] = 0;
                }
                $orderReturnCoupons[$userCouponId] ++;
                if ($orderDiscountCoupon->status == ShopOrderCoupon::STATUS_REFUND) {
                    $orderReturnCoupons[$userCouponId] --;
                }
            }

            foreach ($orderReturnCoupons as $userCouponId => $uses) {
                if ($uses > 0) {
                    continue;
                }
                $userCoupon = UserCoupon::findOne($userCouponId);
                if (!$userCoupon) {
                    continue;
                }
                $userCoupon->model = '';
                $userCoupon->model_id = 0;
                $userCoupon->usage_time = 0;
                $userCoupon->status = UserCoupon::STATUS_DEFAULT;
                if (!$userCoupon->save()) {
                    throw new Exception('用户优惠券退回失败，' . $userCoupon->getErrorMsg());
                }
                $returnCoupons = ArrayHelper::getValue($refundOrderCoupons, $userCouponId);
                if (empty($returnCoupons)) {
                    continue;
                }
                foreach ($returnCoupons as $returnCoupon) {
                    $returnCoupon->status = ShopOrderCoupon::STATUS_REFUND;
                    $returnCoupon->coupon_refund_at = time();
                    if (!$returnCoupon->save()) {
                        throw new Exception('订单优惠券退回失败，' . $returnCoupon->getErrorMsg());
                    }
                }
            }
        }

        return true;
    }

}
